iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
SideProject30

行事曆不再NG:Notion API&Google Calendar跨平台整合發想系列 第 23

Day 23 Notion API & Google Calendar API Integration - Query Notion Database

  • 分享至 

  • xImage
  •  

今天來講Query Notion Database

一樣先上spec

/notion/queryNotionDatabase/{databaseId}:
    post:
      summary: Query data from a Notion database
      parameters:
        - name: databaseId
          in: path
          required: true
          description: ID of the Notion database to query
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                filter:
                  type: object
                  description: JSON object defining query filters
                sorts:
                  type: array
                  items:
                    type: string
      responses:
        '200':
          description: Query results from Notion database
        '400':
          description: Invalid input

今天修改的部分和昨天差不多,所以主要上code就不會解釋太多

Controller

// QueryNotionDatabase godoc
//
//	@Summary		Query Notion Database
//	@Description	Queries a database, returning a paginated array of `Page` objects within the database.
//	@Tags			notion
//	@Accept			json
//	@Produce		json
//	@Param			databaseId	path	string	true	"Database ID"
//	@Param 			request body 	requestModel.NotionQueryDatabaseRequest true	"Request Body"
//	@Success		200		{array}		responseModel.NotionQueryDatabaseResponse
//	@Failure		400		{string}	string			"Invalid input"
//	@Router			/api/v1/notion/queryDatabase/{databaseId} [post]
func (c *Controller) QueryNotionDatabase(ctx *gin.Context) {
	// Get Authorization from config
	configHandler := util.NewConfigHandler()
	auth := configHandler.GetSecretConfig().Get("Authorization")

	databaseId := ctx.Param("databaseId")

	var requests requestModel.NotionQueryDatabaseRequest
	if err := ctx.ShouldBindJSON(&requests); err != nil {
		ctx.JSON(400, gin.H{"error": err.Error()})
		return
	}

	// Marshal the struct to json
	requestJson, err := json.Marshal(requests)
	if err != nil {
		log.Fatalln(err)
	}

	// Send the request to Notion API
	client := handler.NewClient()
	header := map[string]string{
		"Authorization":  auth.(string),
		"Notion-Version": "2022-06-28",
		"Content-Type":   "application/json",
	}
	body := []byte(requestJson)

	response, err := client.Post("https://api.notion.com/v1/databases/"+databaseId+"/query", header, body)
	if err != nil {
		log.Fatalln(err)
	}
	defer response.Body.Close()

	// Change the response body to []byte type
	responseBody, err := io.ReadAll(response.Body)
	if err != nil {
		log.Fatalln(err)
	}
	bodyStr := string(responseBody)
	var data []byte = []byte(bodyStr)

	// Unmarshal the response body to struct
	var responseQueryNotionDatabase responseModel.NotionQueryDatabaseResponse
	json.Unmarshal(data, &responseQueryNotionDatabase)

	ctx.JSON(http.StatusOK, responseQueryNotionDatabase)

}

controller的地方主要就是修改swaggo,controller的地方跟昨天很像

唯一不同的部分為昨天是把request的內容轉成string塞進去[]byte

今天則是直接轉這個資料型態

Request

type NotionQueryDatabaseRequest struct {
	Sorts  []map[string]interface{} `json:"sorts"`
	Filter map[string]interface{}   `json:"filter"`
}

這邊就是加上sorts跟filter的部分

Response

type Database struct {
	Object         string `json:"object"`
	ID             string `json:"id"`
	CreatedTime    string `json:"created_time"`
	LastEditedTime string `json:"last_edited_time"`
	CreatedBy      struct {
		Object string `json:"object"`
		ID     string `json:"id"`
	} `json:"created_by"`
	LastEditedBy struct {
		Object string `json:"object"`
		ID     string `json:"id"`
	} `json:"last_edited_by"`
	Cover  interface{} `json:"cover"`
	Icon   interface{} `json:"icon"`
	Parent struct {
		Type       string `json:"type"`
		DatabaseID string `json:"database_id"`
	} `json:"parent"`
	Archived   bool                   `json:"archived"`
	Properties map[string]interface{} `json:"properties"`
	URL        string                 `json:"url"`
	PublicURL  interface{}            `json:"public_url"`
}

type NotionQueryDatabaseResponse struct {
	Object          string      `json:"object"`
	Results         []Database  `json:"results"`
	NextCursor      interface{} `json:"next_cursor"`
	HasMore         bool        `json:"has_more"`
	Type            string      `json:"type"`
	PageOrDB        struct{}    `json:"page_or_database"`
	DeveloperSurvey string      `json:"developer_survey"`
}

這邊的內容也主要是從官方文件來的

Start building with the Notion API

再利用chatGPT轉成golang的型態

Main

func main() {
	r := gin.Default()

	c := controller.NewController()

	v1 := r.Group("/api/v1")
	{
		notion := v1.Group("/notion")
		{
			notion.POST("/createDatabase/:pageId", c.CreateNotionDatabase)
			notion.POST("/queryDatabase/:databaseId", c.QueryNotionDatabase)
		}
...

這邊主要就是多加一個路徑上去

大概有新增的部分就是這些

接下來做個小小的demo

Demo

Body

{
  "filter":   {
    "and": [
    {
        "property": "Date",
        "date": {
            "on_or_after": "2023-10-08T00:00:00+08:00"
        }
    }, 
    {
        "property": "Date",
        "date": {
            "before": "2023-10-09T00:00:00+08:00"
        }
    }
  ]
  },
  "sorts": [
  ]
}

在DB中加上以上資料

https://ithelp.ithome.com.tw/upload/images/20231008/20140869T8Z28NgLno.png

Response

{
  "object": "list",
  "results": [
    {
      "object": "page",
      "id": "62a2da36-0f63-4438-a177-3481b6d8019f",
      "created_time": "2023-10-08T08:06:00.000Z",
      "last_edited_time": "2023-10-08T08:07:00.000Z",
      "created_by": {
        "object": "user",
        "id": "a57b5d4d-5914-46e7-9dc0-f964bbaf7289"
      },
      "last_edited_by": {
        "object": "user",
        "id": "a57b5d4d-5914-46e7-9dc0-f964bbaf7289"
      },
      "cover": null,
      "icon": null,
      "parent": {
        "type": "database_id",
        "database_id": "937094e2-c60c-499b-ba07-933a77baec7d"
      },
      "archived": false,
      "properties": {
        "Date": {
          "date": {
            "end": "2023-10-08T12:00:00.000+08:00",
            "start": "2023-10-08T09:00:00.000+08:00",
            "time_zone": null
          },
          "id": "s%7D%5CP",
          "type": "date"
        },
        "Title": {
          "id": "title",
          "title": [
            {
              "annotations": {
                "bold": false,
                "code": false,
                "color": "default",
                "italic": false,
                "strikethrough": false,
                "underline": false
              },
              "href": null,
              "plain_text": "Work",
              "text": {
                "content": "Work",
                "link": null
              },
              "type": "text"
            }
          ],
          "type": "title"
        }
      },
      "url": "https://www.notion.so/Work-62a2da360f634438a1773481b6d8019f",
      "public_url": null
    },
    {
      "object": "page",
      "id": "e76378ae-0066-4cfe-883b-a8ede10bf1bf",
      "created_time": "2023-10-08T08:06:00.000Z",
      "last_edited_time": "2023-10-08T08:06:00.000Z",
      "created_by": {
        "object": "user",
        "id": "a57b5d4d-5914-46e7-9dc0-f964bbaf7289"
      },
      "last_edited_by": {
        "object": "user",
        "id": "a57b5d4d-5914-46e7-9dc0-f964bbaf7289"
      },
      "cover": null,
      "icon": null,
      "parent": {
        "type": "database_id",
        "database_id": "937094e2-c60c-499b-ba07-933a77baec7d"
      },
      "archived": false,
      "properties": {
        "Date": {
          "date": {
            "end": "2023-10-08T09:00:00.000+08:00",
            "start": "2023-10-08T07:00:00.000+08:00",
            "time_zone": null
          },
          "id": "s%7D%5CP",
          "type": "date"
        },
        "Title": {
          "id": "title",
          "title": [
            {
              "annotations": {
                "bold": false,
                "code": false,
                "color": "default",
                "italic": false,
                "strikethrough": false,
                "underline": false
              },
              "href": null,
              "plain_text": "GYM",
              "text": {
                "content": "GYM",
                "link": null
              },
              "type": "text"
            }
          ],
          "type": "title"
        }
      },
      "url": "https://www.notion.so/GYM-e76378ae00664cfe883ba8ede10bf1bf",
      "public_url": null
    },
    {
      "object": "page",
      "id": "008ab7be-1a19-4dd8-a425-38f1199f14e0",
      "created_time": "2023-10-08T08:05:00.000Z",
      "last_edited_time": "2023-10-08T08:06:00.000Z",
      "created_by": {
        "object": "user",
        "id": "a57b5d4d-5914-46e7-9dc0-f964bbaf7289"
      },
      "last_edited_by": {
        "object": "user",
        "id": "a57b5d4d-5914-46e7-9dc0-f964bbaf7289"
      },
      "cover": null,
      "icon": null,
      "parent": {
        "type": "database_id",
        "database_id": "937094e2-c60c-499b-ba07-933a77baec7d"
      },
      "archived": false,
      "properties": {
        "Date": {
          "date": {
            "end": "2023-10-08T07:00:00.000+08:00",
            "start": "2023-10-08T06:00:00.000+08:00",
            "time_zone": null
          },
          "id": "s%7D%5CP",
          "type": "date"
        },
        "Title": {
          "id": "title",
          "title": [
            {
              "annotations": {
                "bold": false,
                "code": false,
                "color": "default",
                "italic": false,
                "strikethrough": false,
                "underline": false
              },
              "href": null,
              "plain_text": "commute",
              "text": {
                "content": "commute",
                "link": null
              },
              "type": "text"
            }
          ],
          "type": "title"
        }
      },
      "url": "https://www.notion.so/commute-008ab7be1a194dd8a42538f1199f14e0",
      "public_url": null
    }
  ],
  "next_cursor": null,
  "has_more": false,
  "type": "page_or_database",
  "page_or_database": {},
  "developer_survey": ""
}

可以看到有拿到時間跟content,所以query的部分也完成了


上一篇
Day 22 Notion API & Google Calendar API Integration - Create Notion Database
下一篇
Day 24 Notion API & Google Calendar API Integration - Refactor Architecture and Spec
系列文
行事曆不再NG:Notion API&Google Calendar跨平台整合發想30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言